package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Mr.M
 * @version 1.0
 * @description TODO
 * @date 2023/2/14 12:11
 */
@Service
public class TeachplanServiceImpl implements TeachplanService {

    @Autowired
    TeachplanMapper teachplanMapper;

    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;

    // 根据课程id查询课程计划
    @Override
    public List<TeachplanDto> findTeachplanTree(Long courseId) {
        List<TeachplanDto> teachplanDtos = teachplanMapper.selectTreeNodes(courseId);
        return teachplanDtos;
    }

    private int getTeachplanCount(Long courseId,Long parentId){
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper = queryWrapper.eq(Teachplan::getCourseId, courseId).eq(Teachplan::getParentid, parentId);
        Integer count = teachplanMapper.selectCount(queryWrapper);
        return  count+1;
    }

    // 新增/修改/保存课程计划
    // 通过判断dto中是否有id主键判断是新增还是更新
    @Override
    public void saveTeachplan(SaveTeachplanDto saveTeachplanDto) {
        //通过课程计划id判断是新增和修改
        Long teachplanId = saveTeachplanDto.getId();
        if(teachplanId ==null){
            //新增
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(saveTeachplanDto,teachplan);
            //确定排序字段，找到它的同级节点个数，排序字段就是个数加1  select count(1) from teachplan where course_id=117 and parentid=268
            Long parentid = saveTeachplanDto.getParentid();
            Long courseId = saveTeachplanDto.getCourseId();
            int teachplanCount = getTeachplanCount(courseId, parentid);
            teachplan.setOrderby(teachplanCount);
            teachplanMapper.insert(teachplan);
        }else{
            //修改
            Teachplan teachplan = teachplanMapper.selectById(teachplanId);
            //将参数复制到teachplan
            BeanUtils.copyProperties(saveTeachplanDto,teachplan);
            teachplanMapper.updateById(teachplan);
        }

    }

    // 删除章节
    @Override
    public void deleteTeachPlan(Long id) {
        // 判断是否存在课程
        Teachplan teachplan = teachplanMapper.selectById(id);
        if (teachplan == null)
            XueChengPlusException.cast("课程不存在");
        // 判断删除的是大章节还是小节
        if(teachplan.getGrade()==2){
            // 小节 直接删除小节以及小节关联的数据
            TeachplanMedia teachplanMedia = teachplanMediaMapper.selectByTeachplanId(id);
            teachplanMapper.deleteById(id);
            LambdaQueryWrapper<TeachplanMedia> lb4Media = new LambdaQueryWrapper<>();
            lb4Media.eq(TeachplanMedia::getTeachplanId, id);
            if (teachplanMediaMapper.selectCount(lb4Media) > 0){
                teachplanMediaMapper.deleteById(teachplanMedia.getId());
            }
        } else {
            // 大节 根据课程先查询所有数据 是否有小节 有小节不允许删除,没有小节,直接删除
            List<TeachplanDto> teachplanDtos = teachplanMapper.selectTreeNodes(teachplan.getCourseId());
            // 根据计划id 取出一级节点
            List<TeachplanDto> teacPlanTreeNodes = teachplanDtos.stream().filter(e -> e.getId().equals(teachplan.getId())).collect(Collectors.toList());
            if (teacPlanTreeNodes.get(0).getTeachPlanTreeNodes().size() == 0){
                teachplanMapper.deleteById(id);
            }else{
                XueChengPlusException.cast("本节存在子章节,请确保没有字节在进行删除");
            }
        }

    }

    /**
     * @param teachplanId       课程计划id
     * @param moveStatus 是否是下移 Ture 代表下移 ,False 代表上移
     * @return void
     * @description 课程计划上下移动
     * @author: duyus
     * @date: now
     */
    public void move(Long teachplanId,Boolean moveStatus) {
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        Integer orderBy = teachplan.getOrderby();
        if (!moveStatus) {
            Integer orderByUp = orderBy - 1;
            swap(orderBy,orderByUp,teachplan);
        } else {
            Integer orderByDown = orderBy + 1;
            swap(orderBy,orderByDown,teachplan);
        }
    }

    private void swap(Integer orderBy,Integer order,Teachplan teachplan){
        LambdaQueryWrapper<Teachplan> lqwOrderByUp = new LambdaQueryWrapper<>();
        lqwOrderByUp.eq(orderBy != null, Teachplan::getOrderby, order);
        lqwOrderByUp.eq(Teachplan::getParentid, teachplan.getParentid());
        lqwOrderByUp.eq(Teachplan::getCourseId, teachplan.getCourseId());
        Teachplan teachPlanOrderByUp = teachplanMapper.selectOne(lqwOrderByUp);
        if (teachPlanOrderByUp == null) {
            XueChengPlusException.cast("无法移动此课程");
        }
        teachplan.setOrderby(order);
        teachPlanOrderByUp.setOrderby(orderBy);
        teachplanMapper.updateById(teachplan);
        teachplanMapper.updateById(teachPlanOrderByUp);
    }

    @Transactional
    @Override
    public void associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //课程计划id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan == null){
            XueChengPlusException.cast("课程计划不存在");
        }

        //先删除原有记录,根据课程计划id删除它所绑定的媒资
        int delete = teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId, bindTeachplanMediaDto.getTeachplanId()));

        //再添加新记录
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        BeanUtils.copyProperties(bindTeachplanMediaDto,teachplanMedia);
        teachplanMedia.setCourseId(teachplan.getCourseId());
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMediaMapper.insert(teachplanMedia);

    }
}
